home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
workbench werkzeuge
/
workbench erweiterungen
/
avwm-0.4
/
callbacks.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
3KB
|
158 lines
/*
callbacks for message ports
5/2/93 Bernhard Fastenrath
*/
#include <dos.h>
#include <signal.h>
#include <dos/dos.h>
#include <exec/types.h>
#include <pragmas/exec_pragmas.h>
#include "callbacks.h"
static struct CbPort *find_cbport (struct MsgPort *port);
static struct MinList port_list = { NULL, NULL, NULL };
static ULONG signals = SIGBREAKF_CTRL_C;
ULONG free_signals = 0;
callback signal_callback = NULL;
void
RemoveAllCallbacks ()
{
struct Callback *cnode;
struct CbPort *pnode;
if (!port_list.mlh_Head) return;
while (pnode = RemTail (&port_list))
{
while (cnode = RemTail (&pnode -> callbacks))
free (cnode);
free (pnode);
}
signals = SIGBREAKF_CTRL_C;
}
void
RemoveCallback (struct Callback *cb)
{
struct CbPort *node;
Remove (cb);
free (cb);
if (EmptyMinList (&cb -> cbport -> callbacks)) {
Remove (cb -> cbport);
free (cb -> cbport);
}
signals = SIGBREAKF_CTRL_C | free_signals;
for (node = port_list.mlh_Head; node -> node.mln_Succ; node = node -> node.mln_Succ)
signals |= node -> sig;
}
struct Callback *
AddPortCallback (struct MsgPort *port, callback fun, ULONG class)
{
struct Callback *new_cb;
struct CbPort *pn;
if (!port_list.mlh_Head)
InitListHeader (&port_list);
if (!(pn = find_cbport (port)))
return NULL;
if (!(new_cb = Malloc (struct Callback)))
return NULL;
new_cb -> class = class;
new_cb -> function = fun;
new_cb -> cbport = pn;
AddHead (&pn -> callbacks, new_cb);
return new_cb;
}
void
SetSignalCallback (ULONG signal_mask, callback fun)
{
free_signals = signal_mask;
signals |= free_signals;
signal_callback = fun;
}
void
AppMainLoop ()
{
struct IntuiMessage *msg;
ULONG received = 0;
struct CbPort *pnode;
struct Callback *cnode;
while (!(received & SIGBREAKF_CTRL_C))
{
received = Wait (signals);
if (free_signals & received)
signal_callback (received);
for (pnode = port_list.mlh_Head; pnode -> node.mln_Succ; pnode = pnode -> node.mln_Succ)
{
while (msg = GetMsg (pnode -> port))
{
for (cnode = pnode -> callbacks.mlh_Head; cnode -> node.mln_Succ; cnode = cnode -> node.mln_Succ)
{
/* cnode -> class has to be zero for non-IntuiMessages which
don't have a `class' field following the message struct!
*/
if (!cnode -> class || msg -> Class == cnode -> class)
if (cnode -> function (msg, cnode)) {
msg = NULL;
break;
}
}
if (msg && msg -> ExecMessage.mn_ReplyPort != pnode -> port)
ReplyMsg (msg);
}
}
}
#if 0
printf ("AppMainLoop: User Break detected.\n");
#endif
}
void
InitListHeader (struct MinList *list)
{
list -> mlh_Head = &list -> mlh_Tail;
list -> mlh_TailPred = &list -> mlh_Head;
list -> mlh_Tail = 0;
}
static struct CbPort*
find_cbport (struct MsgPort *port)
{
struct CbPort *pn;
for (pn = port_list.mlh_Head; pn -> node.mln_Succ; pn = pn -> node.mln_Succ)
if (pn -> port == port)
return pn;
if (!(pn = Malloc (struct CbPort)))
return NULL;
pn -> port = port;
signals |= pn -> sig = 1L << port -> mp_SigBit;
InitListHeader (&pn -> callbacks);
AddHead (&port_list, (struct MinNode *) pn);
return pn;
}